﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq.Expressions;

namespace NDasm.Core.UI.Base
{
    public abstract class ObservableObject : INotifyPropertyChanged, INotifyPropertyChanging
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public event PropertyChangingEventHandler PropertyChanging;

        protected void NotifyPropertyChanged(Expression<Func<object>> propertyExpression)
        {
            if (PropertyChanged == null)
            {
                return;
            }
            string name = ReflectionHelper.GetPropertyName(propertyExpression);
            VerifyPropertyName(name);
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs(name));
        }

        protected void NotifyPropertyChanging(Expression<Func<object>> propertyExpression)
        {
            if (PropertyChanging == null)
            {
                return;
            }
            string name = ReflectionHelper.GetPropertyName(propertyExpression);
            VerifyPropertyName(name);
            PropertyChanging.Invoke(this, new PropertyChangingEventArgs(name));
        }

        [Conditional("DEBUG")]
        [DebuggerStepThrough]
        private void VerifyPropertyName(string name)
        {
            if (!ReflectionHelper.VerifyPropertyName(this, name))
            {
                throw new ArgumentException(string.Format("Property {0} doesn't exists in class {1}", name,
                                                          TypeDescriptor.GetClassName(this)));                
            }
        }        
    }
}